package com.liu.stockmarket.ui.setting

import android.Manifest
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.liu.stockmarket.R
import com.liu.stockmarket.StockMarketApplication
import com.liu.stockmarket.VO.Backup
import com.permissionx.guolindev.PermissionX

import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.liu.stockmarket.utils.*
import com.lxj.xpopupext.popup.TimePickerPopup
import java.io.InputStreamReader
import java.nio.charset.Charset
import java.time.LocalDate


class SettingsFragment : PreferenceFragmentCompat() {

    private lateinit var viewModel: SettingsViewModel

    private lateinit var registerForActivityResult: ActivityResultLauncher<String>

    private var backupPreference: Preference? = null

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey)

        val application = this.requireActivity().application as StockMarketApplication
        viewModel = ViewModelProvider(
            this.viewModelStore, SettingsViewModel.SettingsViewModelFactory(
                application.transactionRecordRepository,
                application.stockRepository,
                application.profitRepository
            )
        ).get(SettingsViewModel::class.java)
        backupPreference = findPreference("setting_backup")
        observer()
        listener()

        setPlayDate(getPlayDate())


    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerForActivityResult =
            registerForActivityResult(ActivityResultContracts.GetContent()) {
                if (it == null) {
                    this.requireContext().toast("未选择文件")
                    return@registerForActivityResult
                }
                val openInputStream = this.requireActivity().contentResolver.openInputStream(it)

                val readText =
                    InputStreamReader(openInputStream, Charset.defaultCharset()).readText()
                val backup: Backup = buildGson().fromJson(readText, Backup::class.java)
                viewModel.saveData(backup)

                backup.payDate?.let { ld ->
                    setPlayDate(ld)
                        preferenceManager.sharedPreferences.edit()
                        .putString(getString(R.string.setting_play_date), ld.YMD()).apply()
                }
                this.requireContext().toast("数据恢复成功!")
            }
    }

    private fun setPlayDate(date: LocalDate?) {
        setPlayDate(date?.YMD())
    }

    private fun setPlayDate(dateString: String?) {
        findPreference<Preference>(getString(R.string.setting_play_date))?.summary =
            dateString ?: "未设置"
    }

    private fun listener() {
        backupPreference?.setOnPreferenceClickListener {
            backup()
            true
        }
        findPreference<Preference>("setting_restore")?.setOnPreferenceClickListener {
            restore()
            true
        }

        findPreference<Preference>("setting_clear_data")?.setOnPreferenceClickListener {
            this.requireContext()
                .confirm(getString(R.string.clear_data), getString(R.string.clear_data_tip), {
                    viewModel.clearData()
                    this.requireContext().toast("数据清空完毕")
                })
            true
        }
        findPreference<Preference>("setting_play_date")?.setOnPreferenceClickListener {
            this.requireContext().selectDate(TimePickerPopup.Mode.YMD) { date ->
                setPlayDate(date = date.toLocalDate())
                it.sharedPreferences.edit()
                    .putString(getString(R.string.setting_play_date), date.YMD()).apply()
            }
            true
        }
    }


    private fun observer() {
        viewModel.data.observe(this) {
            val toJson = buildGson().toJson(it)
            val fileName = "data_${System.currentTimeMillis()}.json"
            saveFile(toJson, fileName)
            backupPreference?.summary = "保存在：/download/stockmarket/${fileName}"
            this.requireContext().toast("备份成功,文件名为：$fileName")

        }
    }

    private fun backup() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE

            )
            .request { allGranted, _, _ ->
                if (allGranted) {
                    viewModel.getData(getPlayDate())
                } else {
                    this.requireContext().toast("未授予读写权限，不能备份数据")
                }

            }

    }

    private fun getPlayDate(): String? {
        return preferenceManager.sharedPreferences.getString(
            getString(R.string.setting_play_date),
            null
        )
    }

    private fun restore() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
            .request { allGranted, _, _ ->
                if (allGranted) {

                    val intent = Intent(Intent.ACTION_GET_CONTENT) //  意图：文件浏览器

                    intent.type = "application/json" //无类型限制

                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false) //  关键！多选参数为true
                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true) //  关键！多选参数为true

                    intent.addCategory(Intent.CATEGORY_OPENABLE)
                    registerForActivityResult.launch("application/json")

//                    startActivityForResult(intent, 400)
//                    val readFile = readFile(BACKUP_FILE_NAME)
//                    println(readFile)
//                    val backup: Backup = buildGson().fromJson(readFile, Backup::class.java)
//                    viewModel.saveData(backup)

                } else {
                    this.requireContext().toast("未授予读写权限，不能恢复数据")
                }

            }
    }


    companion object {
    }

}